﻿using LightCAD.Core;
using LightCAD.Core.Elements;
using LightCAD.Runtime;
using SkiaSharp;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
using LightCAD.MathLib;


namespace LightCAD.Drawing.Actions
{
    public class DimArcLengthAction : ElementAction
    {
        public static string CommandName;
        public static LcCreateMethod[] CreateMethods;

        static DimArcLengthAction()
        {
            CommandName = "DIMARC";
            CreateMethods = new LcCreateMethod[1];
            CreateMethods[0] = new LcCreateMethod()
            {
                Name = "DIMARC",
                Description = "DIMARC",
                Steps = new LcCreateStep[]
                {
                    new LcCreateStep{ Name="Step0", Options="选择弧线段或多段线圆弧段:" },
                    new LcCreateStep{ Name="Step1", Options="指定弧长标注位置:" },
                }
            };
            
        }

        internal static void Initilize()
        {
            ElementActions.DimArcLenght = new DimArcLengthAction();
            LcDocument.ElementActions.Add(BuiltinElementType.DimArcLenght, ElementActions.DimArcLenght);
        }

        private PointInputer inputer { get; set; }

        private Vector2 point;
        private Vector2 startpoint;
        private Vector2 endpoint;
        private Vector2 center;
        private double raduis;
    
        public DimArcLengthAction() { }
        public DimArcLengthAction(IDocumentEditor docEditor) : base(docEditor)
        {
            this.commandCtrl.WriteInfo("命令 ：DAL");
        }
        private LcCreateMethod GetMethod(string method)
        {
            if (method == null) return CreateMethods[0];
            var getted= CreateMethods.FirstOrDefault((m) => m.Name == method);
            if (getted == null)
                return CreateMethods[0];
            else
                return getted;
        }
        public async void ExecCreate(string[] args = null)
        {
            this.StartCreating();
            //this.Segments = new List<RolineSegment>();
            var curMethod = SetCurMethod(CreateMethods, 0);
            var ElementInputer = new ElementInputer(this.docEditor);
            this.inputer = new PointInputer(this.docEditor);
            Step0:
            var step0 = SetCurStep(curMethod, 0);


            var result0 = await ElementInputer.Execute(step0.Options);
            if (ElementInputer.isCancelled) { this.Cancel(); return; }
            if (result0 == null)
            {
                this.Cancel();
                goto End;
            }
            if (result0.ValueX == null)
            {
                goto Step0;
            }
            else
            {
                LcElement element = (LcElement)result0.ValueX;
                this.point = (Vector2)result0.Extent;
                if (CreateSelects(element))
                {
                    //记住圆的圆心点 以及半径
                    if (element is LcArc)
                    {

                        var arc = element as LcArc;

                        this.startpoint = arc.Startp;

                        this.endpoint = arc.Endp;

                        goto Step1;

                    }
                }
                else
                {
                    goto Step0;
                }
            }
            Step1:
            var step1 = SetCurStep(curMethod, 1);
            var result1 = await inputer.Execute(step1.Options);
            if (inputer.isCancelled) { this.Cancel(); return; }
            if (result1 == null)
            {
                this.Cancel();
                goto End;
            }
            if (result1.ValueX == null)
            {
                goto Step1;
            }
            else
            {
                if (result1.Option != null)
                {
                  
                }
                else
                {
                    goto Step1;
                }
            }
            this.point = (Vector2)result1.ValueX;

            End:
            this.EndCreating();

        }
        private void CreateDimElement()
        {
            //var doc = this.docRt.Document;
            //DocumentManager.CurrentRecorder.BeginAction("DimDiameter");
            //var DimDiametric = doc.CreateObject<DimDiametric>();
            //DimDiametric.Start = this.point;
            //DimDiametric.End = this.endpoint;
            //DimDiametric.Dimtext =(this.raduis*2).ToString("0.00");
            //doc.ModelSpace.InsertElement(DimDiametric);
            //this.docRt.Action.ClearSelects();
            //DocumentManager.CurrentRecorder.EndAction();
        }
       

        /// <summary>
        /// 选中的对象
        /// </summary>
        /// <param name="elements"></param>
        /// <returns></returns>
        private bool CreateSelects(LcElement elements)
        {
                if (elements is LcArc) {
                    return true;
                }
            return false;

        }


        /// <summary>
        /// 对一个坐标点按照一个中心进行旋转
        /// </summary>
        /// <param name="center">中心点</param>
        /// <param name="p1">要旋转的点</param>
        /// <param name="angle">旋转角度，笛卡尔直角坐标</param>
        /// <returns></returns>
        private Vector2 PointRotate(Vector2 center, Vector2 p1, double angle)
        {
            Vector2 tmp = new Vector2();
            double angleHude = angle * Math.PI / 180;/*角度变成弧度*/
            double x1 = (p1.X - center.X) * Math.Cos(angleHude) + (p1.Y - center.Y) * Math.Sin(angleHude) + center.X;
            double y1 = -(p1.X - center.X) * Math.Sin(angleHude) + (p1.Y - center.Y) * Math.Cos(angleHude) + center.Y;
            tmp.X = (int)x1;
            tmp.Y = (int)y1;
            return tmp;
        }
        public override void Cancel()
        {
            base.Cancel();
            this.vportRt.SetCreateDrawer(null);
        }
       
        

        public override void CreateElement(LcElement element, Matrix3 matrix)
        {
            //DocumentManager.CurrentRecorder.BeginAction("Circle");
            //var dim = element as DimDiametric;
            //this.vportRt.ActiveElementSet.AddDimDiametric(matrix.MultiplyPoint(dim.Start), matrix.MultiplyPoint(dim.End),dim.Dimtext);
            //DocumentManager.CurrentRecorder.EndAction();
        }
        public override void CreateElement(LcElement element,Vector2 basePoint, double scaleFactor)
        {
            //var circle = element as LcCircle;
            //Matrix3d matrix3 = Matrix3d.Scale(scaleFactor, basePoint);
            //this.vportRt.ActiveElementSet.AddCircle(matrix3.MultiplyPoint(circle.Center), circle.Radius * scaleFactor);
        }
        public override void CreateElement(LcElement element, Vector2 basePoint, Vector2 scaleVector)
        {
            //var circle = element as LcCircle;
            //Matrix3d matrix3 = Matrix3d.Scale(scaleVector, basePoint);
            //this.vportRt.ActiveElementSet.AddCircle(matrix3.MultiplyPoint(circle.Center), circle.Radius * Vector2d.Distance(basePoint, scaleVector));
        }
        public override void Draw(SKCanvas canvas, LcElement element, Matrix3 matrix)
        {
            var dim = element as DimDiametric;
            //Vector vector1 = new Vector(20, 30);
            //Double scalar1 = 75;
            //Vector vectorResult = new Vector();

            // Multiply the vector by the scalar.
            // vectorResult is equal to (1500,2250)
          
            var mstart= matrix.MultiplyPoint(dim.Start);
            var mend = matrix.MultiplyPoint(dim.End);
            var mtext =  dim.Dimtext;
            var start = this.vportRt.ConvertWcsToScr(mstart).ToSKPoint();
            var end= this.vportRt.ConvertWcsToScr(mend).ToSKPoint();
            //get Layer color 
            bool isDragCopy = (matrix != Matrix3.Zero);
            var pen = this.GetDrawPen(dim, isDragCopy);
            if (pen == Constants.defaultPen)
            {
                //TODO:这里可以考虑将实线用颜色做KEY，对SKPaint进行缓存
                using (var elePen = new SKPaint { Color = new SKColor(element.GetColorValue()), IsStroke = true })
                {

                    canvas.DrawLine(start,end, elePen);
                    //canvas.DrawText(mtext, start, elePen);
                }
            }
            else
            {
                canvas.DrawLine(start,end, pen);
                //canvas.DrawText(mtext, start, pen);
            }

        }


        public override void DrawAuxLines(SKCanvas canvas)
        {
           
        }

        #region Grip
        public override ControlGrip[] GetControlGrips(LcElement element)
        {
            var dim = element as DimDiametric;

            var grips = new List<ControlGrip>();
            var gripStartr = new ControlGrip
            {
                Element = dim,
                Name = "Start",
                Position = dim.Start
            };
            grips.Add(gripStartr);

            var gripEnd = new ControlGrip
            {
                Element = dim,
                Name = "End",
                Position = dim.End
            };
            grips.Add(gripEnd);

            //var gripText = new ControlGrip
            //{
            //    Element = circle,
            //    Name = "Top",
            //    Position = new Vector2d(circle.Center.X, circle.Center.Y + circle.Radius)
            //};
            //grips.Add(gripTop);

            return grips.ToArray();
        }
        private string _gripName;
        private Vector2 _position;
        private DimDiametric _dim;

        public override void SetDragGrip(LcElement element, string gripName, Vector2 position, bool isEnd)
        {
            var dim= element as DimDiametric;

            _dim = dim;
            //if (!isEnd)
            //{
            //    _gripName = gripName;
            //    _position = position;
            //}
            //else
            //{
            //    if (gripName == "Center")
            //        circle.Set(center: position);
            //    else
            //    {
            //        var r = Vector2d.Distance(circle.Center, position);
            //        circle.Set(radius: r);
            //    }
            //}
        }


        public override void DrawDragGrip(SKCanvas canvas)
        {
            //if (_circle == null) return;

            //var center = this.vportRt.ConvertWcsToScr(_circle.Center);
            //var r = this.vportRt.ConvertWcsToScr(_circle.Radius);
            //if (_gripName == "Center")
            //    center = this.vportRt.ConvertWcsToScr(_position);
            //else
            //{
            //    var wr = Vector2d.Distance(_circle.Center, _position);
            //    r = this.vportRt.ConvertWcsToScr(wr);
            //}
            //canvas.DrawCircle(center.ToSKPoint(), (float)r, Constants.draggingPen);
        }

        #endregion

        public override List<PropertyObserver> GetPropertyObservers()
        {
            return new List<PropertyObserver>();
            //{
            //    new PropertyObserver()
            //    {
            //        Name = "CenterX",
            //        DisplayName = "圆心 X 坐标",
            //        Getter = (ele) => Math.Round((ele as LcCircle).Center.X, 4),
            //        Setter = (ele, value) =>
            //        {
            //            var circle = (ele as LcCircle);
            //            var x = Convert.ToDouble(value);
            //            var cen = new Vector2d(x, circle.Center.Y);
            //            circle.Set(center : cen);
            //        }
            //    },
            //    new PropertyObserver()
            //    {
            //        Name = "CenterY",
            //        DisplayName = "圆心 Y 坐标",
            //        Getter = (ele) => Math.Round((ele as LcCircle).Center.Y, 4),
            //        Setter = (ele, value) =>
            //        {
            //            var circle = (ele as LcCircle);
            //            var y = Convert.ToDouble(value);
            //            var cen = new Vector2d(circle.Center.X, y);
            //            circle.Set(center : cen);
            //        }
            //    },
            //    new PropertyObserver()
            //    {
            //        Name = "Radius",
            //        DisplayName = "半径",
            //        Getter = (ele) => Math.Round((ele as LcCircle).Radius, 4),
            //        Setter = (ele, value) =>
            //        {
            //            var circle = (ele as LcCircle);
            //            var radius = Convert.ToDouble(value);
            //            circle.Set(radius : radius);
            //        }
            //    },
            //    new PropertyObserver()
            //    {
            //        Name = "Diameter",
            //        DisplayName = "直径",
            //        Getter = (ele) => Math.Round((ele as LcCircle).Radius * 2, 4),
            //        Setter = (ele, value) =>
            //        {
            //            var circle = (ele as LcCircle);
            //            var radius = Convert.ToDouble(value) / 2;
            //            circle.Set(radius : radius);
            //        }
            //    },
            //    new PropertyObserver()
            //    {
            //        Name = "Circumference",
            //        DisplayName = "周长",
            //        Getter = (ele) => Math.Round((ele as LcCircle).Radius * 2 * Math.PI, 4),
            //        Setter = (ele, value) =>
            //        {
            //            var circle = (ele as LcCircle);
            //            var radius = Convert.ToDouble(value) / 2 / Math.PI;
            //            circle.Set(radius : radius);
            //        }
            //    },
            //    new PropertyObserver()
            //    {
            //        Name = "Area",
            //        DisplayName = "面积",
            //        Getter = (ele) =>
            //        {
            //            var radius = (ele as LcCircle).Radius;
            //            return Math.Round(Math.Pow(radius, 2) * Math.PI, 4);
            //        },
            //        Setter = (ele, value) =>
            //        {
            //            var circle = (ele as LcCircle);
            //            var area = Convert.ToDouble(value);
            //            var radius = Math.Sqrt(area / Math.PI);
            //            circle.Set(radius : radius);
            //        }
            //    },
            //    new PropertyObserver()
            //    {
            //        Name = "NormalX",
            //        DisplayName = "法向 X 坐标",
            //        Getter = (ele) => 0
            //    },
            //    new PropertyObserver()
            //    {
            //        Name = "NormalY",
            //        DisplayName = "法向 Y 坐标",
            //        Getter = (ele) => 0
            //    },
            //    new PropertyObserver()
            //    {
            //        Name = "NormalZ",
            //        DisplayName = "法向 Z 坐标",
            //        Getter = (ele) => 1
            //    },
            //};
        }
    }
}
